package game;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

import util.Pair;

import exceptions.MatchNotFinishedException;
import exceptions.InvalidMoveException;


/**
 * Match class
 * 
 * Base-class of every game supported by the system.
 * There will be a derived class implementing the logic 
 * for each different game.
 */
public interface Match extends Serializable {

	
	/**
	 * Returns an unique ID used to identify each challenge.
	 * 
	 * @return An unique ID used to identify each challenge.
	 */
	public int getId();
	
	/**
	 * Implements the logic behind a player move.
	 * 
	 * @param player The Player who performed the move
	 * @param move Information related to this move.
	 * @return True if player has won. False otherwise.
	 * @throws InvalidMoveException If the move is not allowed by the rules of the game.
	 */
	public boolean play(Player player, PlayerMove move) throws InvalidMoveException;
	
	
	/**
	 * Terminates the match when a given player gives up.
	 * 
	 * @param player The player who gave up.
	 */
	public void giveUp(Player player);
	
	
	/**
	 * Is the move allowed by the rules of the game?
	 * 
	 * @param player The Player who wants to perform the move
	 * @param move Information related to this move.
	 * @return True if the move is allowed, false otherwise
	 */
	public boolean isValidMove(Player player, PlayerMove move);
	
	
	/**
	 * Is the game over?
	 * 
	 * @return True if the game is over, false otherwise.
	 */
	public boolean isFinished();
		
	
	/**
	 * Starts the game.
	 */
	public void start();
	
	
	/**
	 * Adds a new player to the game.
	 * Must be called before the game starts!
	 * 
	 * @param player The player to add.
	 */
	public void addPlayer(Player player);
	
	
	/**
	 * Who's the next player to play?
	 * 
	 * @return The player who should play next.
	 */
	public Player getNextPlayer();
	
	
	/**
	 * Returns the list of participants for this match.
	 * 
	 * @return The list of players.
	 */
	public List<Player> getPlayers();
	
	
	/**
	 * Who's the winner?
	 * 
	 * @return The player who has won.
	 * @throws MatchNotFinishedException If the game is not yet over.
	 */
	public Player getWinner() throws MatchNotFinishedException;
	
	
	/**
	 * Returns a list of Pair's containing the ranking points obtained by each player.
	 * 
	 * @return A list of Pair's containing the ranking points obtained by each player.
	 * @throws MatchNotFinishedException If the match is not yet over.
	 */
	public List<Pair<Player, Integer>> getRankingPoints() throws MatchNotFinishedException;
	
	
	/**
	 * Returns a list of Pair's containing the score obtained by each player.
	 * 
	 * @return A list of Pair's containing the score obtained by each player.
	 * @throws MatchNotFinishedException If the match is not yet over.
	 */
	public List<Pair<Player, Integer>> getScore() throws MatchNotFinishedException;
	
	
	/**
	 * Counts the number of moves already performed since this game started.
	 * 
	 * @return The number of moves performed in this game.
	 */
	public int countMoves();
	
	
	/**
	 * When did this game start?
	 * 
	 * @return The date the game started.
	 */
	public Date getDateStarted();
	
	
	/**
	 * When did this game ended?
	 * 
	 * @return The date the game ended.
	 */
	public Date getDateEnded() throws MatchNotFinishedException;
}
